package com.cloud.util;

import com.itextpdf.text.*;
import com.itextpdf.text.pdf.*;
import com.itextpdf.tool.xml.XMLWorkerFontProvider;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import com.itextpdf.tool.xml.html.CssAppliers;
import com.itextpdf.tool.xml.html.CssAppliersImpl;
import com.itextpdf.tool.xml.html.Tags;
import com.itextpdf.tool.xml.pipeline.html.HtmlPipelineContext;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.Charset;
import java.util.Properties;

public class PdfUtil {

    private static final Logger LOG = LoggerFactory.getLogger(PdfUtil.class.getName());



    /**
     * 当前系统为Linux
     */
    public static boolean isLinux() {
        Properties prop = System.getProperties();

        String os = prop.getProperty("os.name");
        if (os != null && os.toLowerCase().indexOf("linux") > -1) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 重写 字符设置方法，解决中文乱码问题
     */
    public static class MyFontsProvider extends XMLWorkerFontProvider {
        @Override
        public Font getFont(final String fontname, final String encoding, final boolean embedded, final float size, final int style, final BaseColor color) {
            BaseFont bf = null;
            try {
                bf = BaseFont.createFont("STSongStd-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED);
            } catch (Exception e) {
                LOG.error(e.getMessage());
            }
            Font font = new Font(bf, size, style, color);
            font.setColor(color);
            return font;
        }
    }

    /**
     * PDF生成路径
     */
    public static final String PDF_DOWNLOAD_PATH = File.separator +"tempDir"+File.separator;
 
    /**
     * 导出PDF文件
     * 
     * @param content
     * @param response
     */
    public static void exportPdf(String fileName, String content, HttpServletResponse response) {
 
        FileOutputStream fos = null;
        FileInputStream in = null;
        OutputStream out = null;
        Document document = new Document();
        Document document2 = new Document();
        File newPath = null;
        try {
            if (StringUtils.isEmpty(fileName)) {
                fileName = "123";
            }
            fileName+=".pdf";
            fileName = new String(fileName.getBytes("UTF-8"), "ISO-8859-1");
            String dicPath = new File(".").getCanonicalPath();
            String srcPath = dicPath + PDF_DOWNLOAD_PATH + fileName;
 
            newPath = new File(dicPath + PDF_DOWNLOAD_PATH);
            newPath.mkdirs();
            // 删除临时文件
            boolean success = fileDelete(newPath);

            if (success) {
                newPath.mkdirs();
                File file = new File(srcPath);
                fos = new FileOutputStream(file);
 
                PdfWriter writer = PdfWriter.getInstance(document, fos);
                PdfWriter writer2 = PdfWriter.getInstance(document2, fos);

                document.open();
                document2.open();
                InputStream htmlInput = new ByteArrayInputStream(content.getBytes("UTF-8"));
                // 使用我们的字体提供器，并将其设置为unicode字体样式
                MyFontsProvider fontProvider = new MyFontsProvider();
                fontProvider.addFontSubstitute("lowagie", "garamond");
                fontProvider.setUseUnicode(true);
                CssAppliers cssAppliers = new CssAppliersImpl(fontProvider);
                HtmlPipelineContext htmlContext = new HtmlPipelineContext(cssAppliers);
                htmlContext.setTagFactory(Tags.getHtmlTagProcessorFactory());
                XMLWorkerHelper.getInstance().getDefaultCssResolver(true);
                XMLWorkerHelper.getInstance().parseXHtml(writer, document, htmlInput, null, Charset.forName("UTF-8"),
                                                         fontProvider);
                XMLWorkerHelper.getInstance().parseXHtml(writer, document2, htmlInput, null, Charset.forName("UTF-8"),
                        fontProvider);

                document.close();
                document2.close();
                writer.close();
                writer2.close();
                // 设置文件ContentType类型，这样设置，会自动判断下载文件类型
                response.setContentType("multipart/form-data");
                // 设置响应头，控制浏览器下载该文件
                response.setHeader("content-disposition", "attachment;filename=" + fileName);
                // 读取要下载的文件，保存到文件输入流
                in = new FileInputStream(srcPath);
                // 创建输出流
                out = response.getOutputStream();
                // 创建缓冲区
                byte buffer[] = new byte[1024];
                int len = 0;
                // 循环将输入流中的内容读取到缓冲区当中
                while ((len = in.read(buffer)) > 0) {
                    // 输出缓冲区的内容到浏览器，实现文件下载
                    out.write(buffer, 0, len);
                }
            }
        } catch (DocumentException e) {
            throw new RuntimeException("Export PDF error : ", e);
        } catch (IOException e) {
            throw new RuntimeException("Export PDF error : ", e);
        } catch (Exception e) {
            throw new RuntimeException("Export PDF error : ", e);
        } finally {
            IOUtils.closeQuietly(fos);
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(out);
            if (newPath != null) {
                fileDelete(newPath);
            }
        }
    }


    /**
     * 页眉
     */
    public static String header = "";

    /**
     * 文档字体大小，页脚页眉最好和文本大小一致
     */
    public static int presentFontSize = 12;

    /**
     * 文档页面大小，最好前面传入，否则默认为A4纸张
     */
    public static Rectangle pageSize = PageSize.A4;

    // 基础字体对象
    public static BaseFont bf = null;

    // 利用基础字体生成的字体对象，一般用于生成中文文字
    public static Font fontDetail = null;


    private static void addPage(PdfWriter writer, Document document) {
        try {
            if (bf == null) {
                bf = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", false);
            }
            if (fontDetail == null) {
                fontDetail = new Font(bf, presentFontSize, Font.NORMAL);// 数据体字体
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 1.写入页眉
        ColumnText.showTextAligned(writer.getDirectContent(),
                Element.ALIGN_LEFT, new Phrase(header, fontDetail),
                document.left(), document.top() + 20, 0);
        // 2.写入前半部分的 第 X页/共
        int pageS = writer.getPageNumber();
        String foot1 = "第 " + pageS + " 页 /共";
        Phrase footer = new Phrase(foot1, fontDetail);

        // 3.计算前半部分的foot1的长度，后面好定位最后一部分的'Y页'这俩字的x轴坐标，字体长度也要计算进去 = len
        float len = bf.getWidthPoint(foot1, presentFontSize);

        // 4.拿到当前的PdfContentByte
        PdfContentByte cb = writer.getDirectContent();

        // 5.写入页脚1，x轴就是(右margin+左margin + right() -left()- len)/2.0F
        // 再给偏移20F适合人类视觉感受，否则肉眼看上去就太偏左了
        // ,y轴就是底边界-20,否则就贴边重叠到数据体里了就不是页脚了；注意Y轴是从下往上累加的，最上方的Top值是大于Bottom好几百开外的。
        ColumnText
                .showTextAligned(
                        cb,
                        Element.ALIGN_CENTER,
                        footer,
                        (document.rightMargin() + document.right()
                                + document.leftMargin() - document.left() - len) / 2.0F + 20F,
                        document.bottom() - 20, 0);

        // 6.写入页脚2的模板（就是页脚的Y页这俩字）添加到文档中，计算模板的和Y轴,X=(右边界-左边界 - 前半部分的len值)/2.0F +

    }

    /**
     * 删除文件
     *
     * @param file
     * @return
     */
    private static boolean fileDelete(File file) {
        if (file.isDirectory()) {
            String[] children = file.list();
            // 递归删除目录中的子目录下
            for (int i = 0; i < children.length; i++) {
                boolean success = fileDelete(new File(file, children[i]));
                if (!success) {
                    return false;
                }
            }
        }
        // 目录此时为空，可以删除
        return file.delete();
    }
}